/*
 * @Descripttion: GGB
 * @version: 1.0
 * @Author: GGB
 * @Date: 2022-02-05 11:52:24
 * @LastEditors: GGB
 * @LastEditTime: 2022-02-05 17:17:55
 */
import * as THREE from 'three';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';
// 导入控制器，轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 导入模型解析器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { useWindowEvent } from '@u/event';

class Base3d {
    constructor(selector, onFinish) {
        this.container = document.querySelector(selector);
        this.camera;
        this.renderer;
        this.model;
        this.panzi;
        this.animateAction;
        this.mixer;
        this.scene;
        this.timeoutid;
        this.clock = new THREE.Clock();
        this.onFinish = onFinish;
        this.init();
        this.animate();
        this.progressFn;
    }
    init() {
        // 初始化场景
        this.initScene();
        // 初始化相机
        this.initCamera();
        // 初始化渲染器
        this.initRenderer();
        // 初始化控制器
        this.initControls();
        // 添加物体
        this.addMesh();
        // 监听场景大小改变，调整渲染尺寸
        useWindowEvent("resize", this.onWindowResize.bind(this))
        // window.addEventListener("resize", this.onWindowResize.bind(this));

        // 监听滚轮事件
        // useWindowEvent("mousewheel", this.onMouseWheel.bind(this))
        // window.addEventListener("mousewheel", this.onMouseWheel.bind(this));
    }
    // 初始化场景
    initScene() {
        // this.scene = new THREE.Scene()
        // this.setEnvMap('000')
        this.scene = new THREE.Scene();
        this.setEnvMap("000");
    }
    //初始化相机
    initCamera() {
        this.camera = new THREE.PerspectiveCamera(
            45,
            window.innerWidth / (window.innerHeight - 46),
            0.25,
            200
        );
        this.camera.position.set(-1.8, 0.6, 2.7);

    }

    // 初始化渲染器
    initRenderer() {
        this.renderer = new THREE.WebGLRenderer({ antialias: true })
        // 设置屏幕像素比
        this.renderer.setPixelRatio(window.devicePixelRatio);

        // 渲染尺寸大小
        this.renderer.setSize(window.innerWidth, window.innerHeight - 46);
        // 色调映射
        this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
        this.renderer.toneMappingExposure = 3;

        this.container.appendChild(this.renderer.domElement);
    }
    // 添加环境
    setEnvMap(hdr) {
        new RGBELoader()
            .setPath("./files/hdr/")
            .load(`${hdr}.hdr`, (texture) => {
                texture.mapping = THREE.EquirectangularReflectionMapping
                this.scene.background = texture
                this.scene.environment = texture
            })

    }
    // 控制器
    initControls() {
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    }
    // 渲染
    render() {
        var delta = this.clock.getDelta()
        this.mixer && this.mixer.update(delta);
        this.renderer.render(this.scene, this.camera);
    }
    // 执行动画
    animate() {
        this.renderer.setAnimationLoop(this.render.bind(this));
    }

    // 加载模型
    setModel(modelName) {
        return new Promise((resolve, reject) => {
            const loader = new GLTFLoader().setPath('./files/gltf/');
            loader.load(`${modelName}`, (gltf) => {
                // 移除上一个场景的模型
                this.model && this.model.removeFromParent();
                this.model = gltf.scene.children[0]
                if ('bag2.glb' === modelName && !this.panzi) {
                    this.panzi = gltf.scene.children[5]

                    // 修改摄像头为模型的摄像头
                    // this.camera = gltf.cameras[0]
                    // // 调用动画
                    // this.mixer = new THREE.AnimationMixer(gltf.scene.children[1])
                    // // 取出动画
                    // this.animateAction = this.mixer.clipAction(gltf.animations[0])
                    // // 设置动画播放时长
                    // this.animateAction.setDuration(20).setLoop(THREE.LoopOnce)
                    // // 设置播放完成之后停止
                    // this.animateAction.clampWhenFinished = true
                    // this.animateAction.play()

                    //   设置灯光
                    this.spotlight1 = gltf.scene.children[2].children[0];
                    this.spotlight1.intensity = 1;
                    this.spotlight2 = gltf.scene.children[3].children[0];
                    this.spotlight2.intensity = 1;
                    this.spotlight3 = gltf.scene.children[4].children[0];
                    this.spotlight3.intensity = 1;
                }
                // this.scene.add(this.panzi)
                this.scene.add(gltf.scene)
                // this.scene.add(this.model);
                resolve(`${modelName}添加成功`)
            }, (e) => {
                // console.log("模型加载进度");
                // console.log(e);
                this.progressFn(e);
            })
        })

    }
    // 添加模型
    async addMesh() {
        let res = await this.setModel("bag2.glb");
        this.onFinish(res);
    }

    // 监听窗口的变化
    onWindowResize() {
        this.camera.aspect = window.innerWidth / (window.innerHeight - 46);
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(window.innerWidth, window.innerHeight - 46);
    }
    // 监听滚轮事件
    onMouseWheel(e) {
        // console.log(this.animateAction);
        let timeScale = e.deltaY > 0 ? 1 : -1;
        this.animateAction.setEffectiveTimeScale(timeScale);
        this.animateAction.paused = false;
        this.animateAction.play();
        if (this.timeoutid) {
            clearTimeout(this.timeoutid);
        }
        this.timeoutid = setTimeout(() => {
            // 表示0.5秒之后停下来
            this.animateAction.halt(0.5);
        }, 300);
    }
    // 进度条加载函数
    onProgress(fn) {
        this.progressFn = fn;
    }

}

export default Base3d;